﻿namespace SERFLITEMAX20.Core
{
    using SERFLITEMAX20;
    using SERFLITEMAX20.DataObjects;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text.RegularExpressions;
    using System.Xml;

    public class GameObject : BaseObject
    {
        private int bobberhit;
        private long createdby;
        private int displayid;
        private float facing;
        private Hashtable mhash;
        private string name;
        private enNodeType nodeType;
        private GameobjectTypes typeid;
        private float x;
        private float y;
        private float z;

        public GameObject(int ptr, Main sender) : base(ptr, sender)
        {
            this.nodeType = enNodeType.None;
            this.displayid = -1;
            this.createdby = -1L;
            this.mhash = new Hashtable();
            this.bobberhit = 0;
            this.Update();
        }

        internal void FindName()
        {
            long num = 0L;
            string str = "";
            int bytes = 0x40;
            int num3 = 0x7d0;
            int num4 = 200;
            if ((num == 0L) || (base.Guid == num))
            {
                SortedList<string, string> list = new SortedList<string, string>();
                for (int i = base.ptrBase; i <= (base.ptrBase + num3); i++)
                {
                    int num6 = base.sender.Memory.ReadInteger(i);
                    if (num6 > 0)
                    {
                        for (int j = 0; j < num4; j++)
                        {
                            int address = base.sender.Memory.ReadInteger(num6 + j);
                            if (address > 0)
                            {
                                this.name = base.sender.Memory.ReadString(address, bytes);
                                if ((((str.Length == 0) || (this.name.IndexOf(str) != -1)) && (Regex.IsMatch(this.name, "^[a-zA-Z]+") && (this.name.Length > 3))) && !list.ContainsKey(this.name))
                                {
                                    string[] strArray = new string[] { "base: ", (i - base.ptrBase).ToString(), " off: ", j.ToString(), " value: ", this.name };
                                    string str2 = string.Concat(strArray);
                                    list.Add(this.name, str2);
                                    Debug.WriteLine(str2);
                                }
                            }
                        }
                    }
                }
            }
        }

        public override XmlElement GetXMLElement(XmlDocument pDom)
        {
            XmlElement xMLElement = base.GetXMLElement(pDom);
            xMLElement.SetAttribute("name", this.Name);
            xMLElement.SetAttribute("x", this.x.ToString());
            xMLElement.SetAttribute("y", this.y.ToString());
            xMLElement.SetAttribute("z", this.z.ToString());
            xMLElement.SetAttribute("facing", this.facing.ToString());
            xMLElement.SetAttribute("flags", this.Flags.ToString());
            xMLElement.SetAttribute("typeid", ((int) this.TypeId).ToString());
            xMLElement.SetAttribute("nodetype", ((int) this.NodeType).ToString());
            xMLElement.SetAttribute("createdby", this.CreatedBy.ToString());
            return xMLElement;
        }

        public override bool Update()
        {
            bool flag = base.Update();
            if (flag)
            {
                this.typeid = (GameobjectTypes) base.sender.Memory.ReadByte(base.ptrBase + Addresses.OFFSET_GAMEOBJECT_TYPEID);
                if (this.typeid == GameobjectTypes.TRANSPORT)
                {
                    this.x = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_TransportPosX);
                    this.y = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_TransportPosY);
                    this.z = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_TransportPosZ);
                    this.facing = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_TransportFacing);
                }
                else if (this.typeid == GameobjectTypes.MO_TRANSPORT)
                {
                    this.x = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_MoTransportPosX);
                    this.y = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_MoTransportPosY);
                    this.z = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_MoTransportPosZ);
                    this.facing = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_MoTransportFacing);
                }
                else
                {
                    this.x = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_PosX);
                    this.y = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_PosY);
                    this.z = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_PosZ);
                    this.facing = base.sender.Memory.ReadFloat(base.ptrBase + Addresses.OFFSET_GameObject_Facing);
                }
                if (this.name == null)
                {
                    int num = base.sender.Memory.ReadInteger(base.ptrBase + Addresses.OFFSET_GAMEOBJECT_NAME_DB);
                    if (num <= 0)
                    {
                        return flag;
                    }
                    int address = base.sender.Memory.ReadInteger(num + Addresses.OFFSET_GAMEOBJECT_NAME);
                    if (address > 0)
                    {
                        this.name = base.sender.Memory.ReadString(address, 0x40);
                    }
                }
                return flag;
            }
            this.x = this.y = this.z = this.facing = 0f;
            return flag;
        }

        public bool Bobbing
        {
            get
            {
                if (base.sender.Memory.ReadByte(base.BasePtr + Addresses.OFFSET_GAMEOBJECT_BOBBER_BOBBING) == 1)
                {
                    this.bobberhit++;
                }
                else
                {
                    this.bobberhit = 0;
                }
                return (this.bobberhit > 2);
            }
        }

        public override long CreatedBy
        {
            get
            {
                if (this.createdby == -1L)
                {
                    this.createdby = base.ReadStorageLong(UpdateFields.OBJECT_END);
                }
                return this.createdby;
            }
        }

        public override int DisplayID
        {
            get
            {
                if (this.displayid == -1)
                {
                    this.displayid = base.ReadStorageInt(UpdateFields.ITEM_FIELD_CONTAINED);
                }
                return this.displayid;
            }
        }

        public override int DynFlags
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.ITEM_FIELD_STACK_COUNT);
            }
        }

        public override float Facing
        {
            get
            {
                return this.facing;
            }
        }

        public override int Flags
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.GAMEOBJECT_FLAGS);
            }
        }

        public override int Level
        {
            get
            {
                return base.ReadStorageInt(UpdateFields.ITEM_FIELD_SPELL_CHARGES);
            }
        }

        public override string Name
        {
            get
            {
                if (this.name != null)
                {
                    return this.name;
                }
                return "";
            }
        }

        public override enNodeType NodeType
        {
            get
            {
                if (this.nodeType == enNodeType.None)
                {
                    int entry = base.Entry;
                    if (entry != 0)
                    {
                        if (Support.gameobjectList.ContainsKey(entry))
                        {
                            SERFLITEMAX20.DataObjects.GameObject obj2 = Support.gameobjectList[entry];
                            if (obj2.subtype > 0)
                            {
                                this.nodeType = (enNodeType) obj2.subtype;
                            }
                            this.name = obj2.name;
                            return this.nodeType;
                        }
                        this.nodeType = enNodeType.Unknown;
                    }
                }
                return this.nodeType;
            }
        }

        public override GameobjectTypes TypeId
        {
            get
            {
                this.typeid = (GameobjectTypes) base.sender.Memory.ReadByte(base.ptrBase + Addresses.OFFSET_GAMEOBJECT_TYPEID);
                return this.typeid;
            }
        }

        public override float X
        {
            get
            {
                return this.x;
            }
        }

        public override float Y
        {
            get
            {
                return this.y;
            }
        }

        public override float Z
        {
            get
            {
                return this.z;
            }
        }
    }
}

